package online.longzipeng.cinemasys.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import online.longzipeng.cinemasys.common.exception.AppException;
import online.longzipeng.cinemasys.common.result.Result;
import online.longzipeng.cinemasys.config.AlipayConfig;
import online.longzipeng.cinemasys.dto.session.SessionQueryResponseDTO;
import online.longzipeng.cinemasys.entity.OrderDetail;
import online.longzipeng.cinemasys.entity.OrderHead;
import online.longzipeng.cinemasys.entity.Seat;
import online.longzipeng.cinemasys.entity.Session;
import online.longzipeng.cinemasys.service.OrderDetailService;
import online.longzipeng.cinemasys.service.OrderHeadService;
import online.longzipeng.cinemasys.service.SeatService;
import online.longzipeng.cinemasys.service.SessionService;
import online.longzipeng.cinemasys.vo.pay.PayVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lzp
 * @date 2021/5/1 11:41
 */
@Controller
@RequestMapping("/pay")
@Api(value = "客户相关接口",description = "客户相关接口",tags = "客户相关接口")
public class AplayController {

    @Autowired
    private SessionService sessionService;
    @Autowired
    private SeatService seatService;
    @Autowired
    private OrderHeadService orderHeadService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private  RedisTemplate redisTemplate;

    private DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @GetMapping("/start")
    @ResponseBody
    public String payStart() {
        return "支付成功回调地址";
    }

    @GetMapping("/end")
    public String payEnd(String out_trade_no) {
        // 支付成功 修改订单状态
        /// 先通过订单号查询订单
        QueryWrapper<OrderHead> qwOrderHead = new QueryWrapper<>();
        qwOrderHead.eq("num",out_trade_no);
        OrderHead orderHead = orderHeadService.getOne(qwOrderHead);
        // 修改订单状态为已支付
        orderHead.setStatus(1);
        orderHeadService.updateById(orderHead);
        return "redirect:http://www.longzipeng.online:9997/#/order";
    }

    /**
     * 方法实现说明 支付宝支付
     * @author      金刚
     * @date        2020/10/14 17:12
     */
    @ApiOperation(value = "支付宝扫码支付",tags = "支付入口")
    @GetMapping(value = "aliPay")
    @ResponseBody
    public Result goAlipay(String orderNum, HttpServletRequest httpRequest , HttpServletResponse httpResponse) throws Exception {
        // 先查订单
        QueryWrapper<OrderHead> qwOrderHead = new QueryWrapper<>();
        qwOrderHead.eq("num",orderNum);
        OrderHead orderHead = orderHeadService.getOne(qwOrderHead);
        if (orderHead == null) {
            throw new AppException("750",orderNum+" 订单不存在！！",null);
        }
        //省略业务代码
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = String.valueOf(orderNum);
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        //这里设置支付后跳转的地址
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        alipayRequest.setBizContent(JSON.toJSONString(alipayClient));
        //付款金额，必填
        BigDecimal allPrice = orderHead.getAllPrice();
        String total_amount = String.valueOf(allPrice);
        //订单名称，必填
        String subject ="订购座位";
        //商品描述，可空
        // 查询影厅以及座位
        // 先查询订单详情
        QueryWrapper<OrderDetail> qwOrderDetail = new QueryWrapper<>();
        qwOrderDetail.eq("order_head_id",orderHead.getId());
        List<OrderDetail> orderDetailList = orderDetailService.list(qwOrderDetail);
        // 订单详情中提取座位
        List<Long> seatIds = orderDetailList.stream().map(OrderDetail::getSeatId).collect(Collectors.toList());
        // 订单详情中获取电影及场次信息
        SessionQueryResponseDTO sessionQueryResponseDTO = sessionService.findById(orderDetailList.get(0).getSessionId());
        // 座位id集合获取座位
        QueryWrapper<Seat> qwSeat = new QueryWrapper<>();
        qwSeat.in("id",seatIds);
        List<Seat> seats = seatService.list(qwSeat);
        // 拼接支付商品内容
        StringBuilder sb = new StringBuilder(sessionQueryResponseDTO.getMovie().getName());
        sb.append("  ");
        sb.append(dtf.format(sessionQueryResponseDTO.getStartTime()));
        sb.append("  ");
        sb.append(sessionQueryResponseDTO.getHall().getName());
        sb.append("  ");
        seats.forEach(seat -> {
            sb.append(seat.getName());
            sb.append(" ");
        });
        String body = sb.toString();
        // 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        String timeout_express = "5m";
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        //  String result = alipayClient.pageExecute(alipayRequest).getBody();
        AlipayTradePagePayResponse response = alipayClient.pageExecute(alipayRequest);
        String body1 = response.getBody();  // 注意 这个是调起支付扫码的，但是不是获取二维码的，他这个返回来的是个form标签
        //  我们只需要将返回的这个标签进行跳转就行了，二维码是跳转之后就出来的，不用考虑获取二维码
        httpResponse.setContentType("text/html;charset="+ AlipayConfig.charset);
        httpResponse.getWriter().write(body1);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
        if (response.isSuccess()){
            return Result.success();
        }else {
            return Result.failed();
        }
    }

}
